// Header Protection
#ifndef _STRING_H_
#define _STRING_H_

// Include Files
#include "Definitions.h"
#include <Windows.h>

// Namespace
namespace IE
{
	/////////////////////////////////////////////////////////////////////////////////
	// Contains a character array and manipulates it as a single piece of data.
	class string_t
	{
	public:     // methods

		// A constructor which create an empty string.
		string_t();

		// A constructor which creates a string from a single character.
		// _cText: char_t - the character to make into a string
		string_t( char_t _cText );

		// A constructor which creates a string from a character array.
		// _szText: char_t const * const - the character array to copy into a string
		string_t( char_t const * const _szText );

		// A constructor which creates a string from another string.
		// _strText: string_t const & - the string to copy.
		string_t( string_t const & _strText );

		// A constructor which creates a string from a multi-byte character array.
		// _szText: char const * const - the character array to copy into a string
		explicit string_t (char const * const _szText );

		// Destructor.
		~string_t() { if( m_szData ) delete[] m_szData; }

		// Copy a portion of the string.
		// _uStart: uint_t - the index at which to start copying
		// _uLength: uint_t - the number of characters to copy, if this is left out, 
		//     the string will be copied to the end
		// return: string_t - the string between the start and end indices
		string_t Substring( uint_t _uStart );
		string_t Substring( uint_t _uStart, uint_t _uLength );

		// Find the first instance of a character within the string
		// _cSearch: char_t - the character to look for
		// _uStart: uint_t - the index in the string at which to start the search, 
		//     by default the search will start at the beginning of the string
		// return: int_t - the index of the first time the character appears in the 
		//     string, or -1 if it does not appear
		int_t IndexOf( char_t _cSearch );
		int_t IndexOf( char_t _cSearch, uint_t _uStart );

		// Find the last instance of a character within the string
		// _char: char_t - the character to look for
		// _cSearch: uint_t - the index in the string at which to start the search, 
		//     by default the search will start at the end of the string
		// return: int_t - the index of the last time the character appears in the 
		//     string, or -1 if it does not appear
		int_t LastIndexOf( char_t _cSearch );
		int_t LastIndexOf( char_t _cSearch, uint_t _uStart );

		// Converts this string to multi-byte. Call with a CE_NULL buffer in order 
		//     to find the required buffer size.
		// _szBuffer: char * - the buffer to fill with the multi-byte string
		// _uBufferSize: uint_t - the size of the buffer
		// return: int_t - the size in bytes of the converted string.
		inline int_t ToMultiByte( char * _szBuffer, uint_t _uBufferSize )
		{
			return WideCharToMultiByte( 
				CP_UTF8, 0, m_szData, m_uLength, _szBuffer, _uBufferSize, 0, 0 
				);
		}

	public:     // operators

		// Make this string a copy of another character, character array, or string.
		// return: string_t & - this string
		string_t & operator =( char_t _cText );
		string_t & operator =( char_t const * const _szText );
		string_t & operator =( string_t const & _strText );

		// Retrieve the character at the given index.
		// _iIndex: uint_t - the index to get the character from
		// return: char_t const & - the character at the given index
		char_t const & operator [] ( uint_t _iIndex ) const
		{ return m_szData[_iIndex]; }

		// retrieve the internal character array for reading
		// return: char_t const * - the internal string data
		operator char_t const *() const { return m_szData; }

		// Concatenate this string and another character, character array, or string
		// return: string_t - a new string created from the string and text
		string_t operator +( char_t _cText );
		string_t operator +( char_t const *_szText );
		string_t operator +( string_t const &_strText );
		friend string_t operator +( char_t _cText, string_t const &_strText );
		friend string_t operator +( 
			char_t const *_szText, string_t const &_strText );

		// Append another character, character array, or string to this one
		// return: string_t & - this string after the given text is appended
		string_t & operator +=( char_t _cText );
		string_t & operator +=( char_t const *_szText );
		string_t & operator +=( string_t const &_strText );

		// Compare this string with another character, character array, or string.
		// return: bool_t - the result of the comparison
		bool_t operator ==( char_t _cText );
		bool_t operator ==( char_t const * _szText );
		bool_t operator ==( string_t const & _strText );
		friend bool_t operator ==( char_t _cText, string_t const & _strText );
		friend bool_t operator ==( 
			char_t const * _szText, string_t const & _strText );

		bool_t operator !=( char_t _cText );
		bool_t operator !=( char_t const * _szText );
		bool_t operator !=( string_t const & _strText );
		friend bool_t operator !=( char_t _cText, string_t const & _strText );
		friend bool_t operator !=( 
			char_t const * _szText, string_t const & _strText );

		bool_t operator >( char_t _cText );
		bool_t operator >( char_t const * _szText );
		bool_t operator >( string_t const & _strText );
		friend bool_t operator >( char_t _cText, string_t const & _strText );
		friend bool_t operator >( 
			char_t const * _szText, string_t const & _strText );

		bool_t operator <( char_t _cText );
		bool_t operator <( char_t const * _szText );
		bool_t operator <( string_t const & _strText );
		friend bool_t operator <( char_t _cText, string_t const & _strText );
		friend bool_t operator <( 
			char_t const * _szText, string_t const & _strText );

		bool_t operator >=( char_t _cText );
		bool_t operator >=( char_t const * _szText );
		bool_t operator >=( string_t const & _strText );
		friend bool_t operator >=( char_t _cText, string_t const & _strText );
		friend bool_t operator >=( 
			char_t const * _szText, string_t const & _strText );

		bool_t operator <=( char_t _cText );
		bool_t operator <=( char_t const * _szText );
		bool_t operator <=( string_t const & _strText );
		friend bool_t operator <=( char_t _cText, string_t const & _strText );
		friend bool_t operator <=( 
			char_t const * _szText, string_t const & _strText );

	private:    // data
		uint_t   m_uLength;
		char_t * m_szData;
	};
}

// Header Protection
#endif // _STRING_H_
